﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Rename.Util
{
    public class FileIconExtractor
    {
        // 导入Windows API
        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }

        [DllImport("shell32.dll")]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

        [DllImport("user32.dll")]
        private static extern bool DestroyIcon(IntPtr hIcon);

        // 常量定义
        private const uint SHGFI_ICON = 0x000000100;     // 获取图标
        private const uint SHGFI_LARGEICON = 0x000000000; // 大图标
        private const uint SHGFI_SMALLICON = 0x000000001; // 小图标
        private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // 使用文件属性

        /// <summary>
        /// 获取文件关联图标
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="isLargeIcon">是否返回大图标（32x32），否则返回小图标（16x16）</param>
        /// <returns>图标对象，失败时返回null</returns>
        public static Icon GetFileIcon(string filePath, bool isLargeIcon = true)
        {
            if (string.IsNullOrEmpty(filePath))
                return null;

            SHFILEINFO shfi = new SHFILEINFO();
            uint flags = SHGFI_ICON | (isLargeIcon ? SHGFI_LARGEICON : SHGFI_SMALLICON);

            // 如果文件不存在，使用文件属性来获取图标（例如获取.txt的图标）
            if (!System.IO.File.Exists(filePath) && !System.IO.Directory.Exists(filePath))
            {
                flags |= SHGFI_USEFILEATTRIBUTES;
            }

            // 调用API获取图标信息
            IntPtr hImgSmall = SHGetFileInfo(filePath, 0, ref shfi, (uint)Marshal.SizeOf(shfi), flags);

            if (hImgSmall == IntPtr.Zero || shfi.hIcon == IntPtr.Zero)
                return null;

            // 将句柄转换为Icon对象
            Icon icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone();

            // 释放图标句柄，避免内存泄漏
            DestroyIcon(shfi.hIcon);

            return icon;
        }
    }
}
